package dispatcher;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedList;

import battlestein.GameEngine;
/**
 * 
 * @author LocoRocoBattleStein
 *
 */
	public class ServerDispatcher implements InterfaceDispatcher, Runnable{

		private ServerSocket socket;
		private Thread t;
		private LinkedList<ClientListener> clients;
		private LinkedList<String> requests;
		private GameEngine GE;
		
		public ServerDispatcher(GameEngine ge, int port) {
			GE = ge;
			clients= new LinkedList<ClientListener>();
			requests= new LinkedList<String>();
			
			try {
				socket = new ServerSocket(port);
				System.out.println("socket opened");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			t = new Thread(this);
			t.start();
		}
		
		public void run() {
			while(true) {
				System.out.println("server is running");
				try {
					if(clients.size() < 4) {
						System.out.println("accept client");
						Socket s = socket.accept();
						ClientListener cl = new ClientListener(s, this);
						clients.add(cl);
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
		public void addRequest(String request) {
			synchronized(requests) {
				requests.add(request);
				
				for(String r: requests) {
					this.processRequest(r);
				}
			}
		}
		
		public void processRequest(String request) {
			String[] words = request.split(" ");
			System.out.println("REQUEST :"+request+" words "+words[0]);
			
			if(words[0].equals("newPlayer")) {
				this.newPlayer();
			}
			else if(words[0].equals("setDestBase")) {
				this.setDestBase(Integer.parseInt(words[1]), Integer.parseInt(words[2]));
			}
			else if(words[0].equals("addTower")) {
				this.addTower(Integer.parseInt(words[1]), Integer.parseInt(words[2]), 
						      Integer.parseInt(words[3]), Integer.parseInt(words[4]));
			}
			else if(words[0].equals("upgradeTower")) {
				this.upgradeTower(Integer.parseInt(words[1]), Integer.parseInt(words[2]), 
					Integer.parseInt(words[3]), Integer.parseInt(words[4]), Integer.parseInt(words[5]));
			}
		}
		
		public void setNetwork(String network) {
		}
		
		public void startGame(int idPlayer) {
			String request = "startGame "+idPlayer+"\n";
			for(ClientListener cl : clients) {
				System.out.println("START");
				cl.sendRequest(request);
			}
		}

		public void updateTower(int id, int idPlayer, int x, int y) {
			String request = "updateTower "+id+" "+idPlayer+" "+x+" "+y+"\n";
			for(ClientListener cl : clients) {
				System.out.println("UPDATING TOWER");
				cl.sendRequest(request);
			}
		}
		
		public void updateTower(int id, int rate, int range, int life, int velocity) {
			String request = "updateTower "+id+" "+rate+" "+range+" "+life+" "+velocity+"\n";
			for(ClientListener cl : clients) {
				cl.sendRequest(request);
			}
		}
		
		public void updateDestBase(int src, int dest) {
			String request = "updateDestBase "+src+" "+dest+"\n";
			for(ClientListener cl : clients) {
				cl.sendRequest(request);
			}
		}
		
		public void newPlayer() {
			synchronized(GE) {
				GE.newPlayer();
			}
		}

		public void setDestBase(int src, int dest) {
			synchronized(GE) {
				GE.setDestBase(src, dest);
			}
			this.updateDestBase(src, dest);
		}

		public void upgradeTower(int id, int rate, int range, int life, int velocity) {
			synchronized(GE) {
				GE.upgradeTower(id, rate, range, life, velocity);
			}
		}

		public void addTower(int id, int idPlayer, int x, int y) {
			synchronized(GE) {
				GE.addTower(id, idPlayer, x, y);
			}
		}


		/**
		 * Getter of the property <tt>GE</tt>
		 * 
		 * @return Returns the GE.
		 * 
		 */

		public GameEngine getGE() {
			return GE;
		}

		/**
		 * Setter of the property <tt>GE</tt>
		 * 
		 * @param GE
		 *            The GE to set.
		 * 
		 */
		public void setGE(GameEngine GE) {
			this.GE = GE;
		}

	}
